unit UMover;

interface

uses XMLIntf, XMLDoc, Types, TypInfo,

  Ucommon;

type

  TNodeMaker = class(TObject)
  class function MakeBounce(zl, zt, zr, zb, xp, yp, ow, oh, xs, ys: Integer): IXMLNode;

  end;



  TMoveParam = (mpZLeft, mpZTop, mpZRight, mpZBottom, mpXPos, mpYPos, mpObjWd,
    mpObjHg, mpXSpeed, mpYSpeed);

  TMover = class(TObject)
  private
    FVals: array[TMoveParam] of Integer;
    function GetVals(Index: TMoveParam): Integer;
    procedure SetVals(Index: TMoveParam; const Value: Integer);
  public
    constructor Create(Node: IXMLNode); virtual;
    function Move(var Apnt: TPoint): boolean; virtual;
    property Vals[Index: TMoveParam]: Integer read GetVals write SetVals;
  end;

  TBouncer = class(TMover)
  public
    function Move(var Apnt: TPoint): boolean; override;
  end;

implementation

{ TMover }

constructor TMover.Create(Node: IXMLNode);
var
  i: TMoveParam;
  ptr : Pointer;   
begin
  Assert(Node <> nil, SBadMoverArg);
  ptr := TypeInfo(TMoveParam);
  for i := Low(TMoveParam) to High(TMoveParam) do
    FVals[i] := Node.ChildNodes.FindNode(GetEnumName(ptr, Ord(i))).NodeValue;
end;

function TMover.GetVals(Index: TMoveParam): Integer;
begin
  Result := FVals[Index];
end;

function TMover.Move(var Apnt: TPoint): boolean;
begin
  Apnt.X := 0;
  Apnt.Y := 0;
  result := False;
end;

procedure TMover.SetVals(Index: TMoveParam; const Value: Integer);
begin
  FVals[Index] := Value;
end;

{ TBouncer }


function TBouncer.Move(var Apnt: TPoint): boolean;
begin
  if ((Vals[mpXPos] + Vals[mpObjWd] + Vals[mpXSpeed] > Vals[mpZRight]) and
    (Vals[mpXSpeed] > 0)) or ((Vals[mpXPos] + Vals[mpXSpeed] < Vals[mpZLeft]) and
    (Vals[mpXSpeed] < 0)) then
    Vals[mpXSpeed] := - Vals[mpXSpeed];
  if ((Vals[mpYPos] + Vals[mpObjHg] + Vals[mpYSpeed] > Vals[mpZBottom]) and
    (Vals[mpYSpeed] > 0)) or ((Vals[mpYPos] + Vals[mpYSpeed] < Vals[mpZTop]) and
    (Vals[mpYSpeed] < 0)) then
    Vals[mpYSpeed] := - Vals[mpYSpeed];

  Vals[mpXPos] := Vals[mpXPos] + Vals[mpXSpeed];
  Vals[mpYPos] := Vals[mpYPos] + Vals[mpYSpeed];
  Apnt.X := Vals[mpXSpeed];
  Apnt.Y := Vals[mpYSpeed];

  Result := True;
end;

{ TNodeProvider }

class function TNodeMaker.MakeBounce(zl, zt, zr, zb, xp, yp, ow, oh, xs, ys : Integer): IXMLNode;
var
  Doc : TxmlDocument;
  ptr : Pointer;
begin
  Doc := TXMLDocument.Create(nil); // when (nil), then auto-freed
  Doc.Active := True;
  Result := Doc.AddChild('a');
  ptr := TypeInfo(TMoveParam);
  Result.AddChild(GetEnumName(ptr, Ord(mpXPos))).NodeValue := xp;
  Result.AddChild(GetEnumName(ptr, Ord(mpYPos))).NodeValue := yp;
  Result.AddChild(GetEnumName(ptr, Ord(mpZLeft))).NodeValue := zl;
  Result.AddChild(GetEnumName(ptr, Ord(mpZTop))).NodeValue := zt;
  Result.AddChild(GetEnumName(ptr, Ord(mpZRight))).NodeValue := zr;
  Result.AddChild(GetEnumName(ptr, Ord(mpZBottom))).NodeValue := zb;
  Result.AddChild(GetEnumName(ptr, Ord(mpObjWd))).NodeValue := ow;
  Result.AddChild(GetEnumName(ptr, Ord(mpObjHg))).NodeValue:= oh;
  Result.AddChild(GetEnumName(ptr, Ord(mpXSpeed))).NodeValue := xs;
  Result.AddChild(GetEnumName(ptr, Ord(mpYSpeed))).NodeValue := ys;
end;

end.

